﻿namespace Resharper.Abstractions.CodeDom.TreeNodes
{
  using System;
  using JetBrains.Annotations;
  using JetBrains.ReSharper.Psi.Tree;

  /// <summary>Defines the <see cref="TreeNode"/> class.</summary>
  public class TreeNode
  {
    #region Constructors and Destructors

    /// <summary>Initializes a new instance of the <see cref="TreeNode"/> class.</summary>
    /// <param name="treeNode">The tree node.</param>
    internal TreeNode([NotNull] ITreeNode treeNode)
    {
      if (treeNode == null)
      {
        throw new ArgumentNullException("treeNode");
      }

      this.InternalTreeNode = treeNode;
    }

    #endregion

    #region Properties

    /// <summary>
    /// Gets or sets the internal tree node.
    /// </summary>
    /// <value>The internal tree node.</value>
    [NotNull]
    internal ITreeNode InternalTreeNode { get; set; }

    #endregion

    #region Public Methods

    /// <summary>Determines whether the specified offset contains caret.</summary>
    /// <param name="offset">The offset.</param>
    /// <returns><c>true</c> if the specified offset contains caret; otherwise, <c>false</c>.</returns>
    public bool ContainsCaretOffset(int offset)
    {
      var range = this.InternalTreeNode.GetNavigationRange();

      return range.TextRange.Contains(offset);
    }

    /// <summary>Determines whether [contains] [the specified tree node].</summary>
    /// <param name="treeNode">The tree node.</param>
    /// <returns><c>true</c> if [contains] [the specified tree node]; otherwise, <c>false</c>.</returns>
    public bool Contains([NotNull] TreeNode treeNode)
    {
      if (treeNode == null)
      {
        throw new ArgumentNullException("treeNode");
      }

      return this.InternalTreeNode.Contains(treeNode.InternalTreeNode);
    }

    /// <summary>Gets the range.</summary>
    /// <returns>Returns the range.</returns>
    public Range GetRange()
    {
      var range = this.InternalTreeNode.GetNavigationRange();

      return new Range(range.TextRange.StartOffset, range.TextRange.EndOffset);
    }

    /// <summary>Returns a <see cref="System.String"/> that represents this instance.</summary>
    /// <returns>A <see cref="System.String"/> that represents this instance.</returns>
    public override string ToString()
    {
      return this.InternalTreeNode.GetText() ?? string.Empty;
    }

    #endregion
  }
}